home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_058 / bigview / readilbm.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  7KB  |  255 lines

  1. #include "iff.h"
  2.  
  3. extern void *IntuitionBase,*GfxBase,*DiskfontBase;
  4.  
  5. /* READILBM.C : NewZAP support routines - (c) 1986 John Hodgson */
  6.  
  7. #define DISK_ERR   1  /* error processing */
  8. #define IFF_ERR    2
  9. #define OUT_OF_MEM 3
  10. #define EXPAND_ERR 4
  11. #define BAD_MODE   5
  12.  
  13. #define MakeID(a,b,c,d) ((a)<<24L | (b)<<16L | (c)<<8 | (d))
  14.  
  15. #define ID_FORM MakeID('F','O','R','M')
  16. #define ID_ILBM MakeID('I','L','B','M')
  17. #define ID_BMHD MakeID('B','M','H','D')
  18. #define ID_CAMG MakeID('C','A','M','G')
  19. #define ID_CMAP MakeID('C','M','A','P')
  20. #define ID_BODY MakeID('B','O','D','Y')
  21.  
  22. #define cmpByteRun1 1
  23.  
  24. #define ROUNDODDUP(a) (((a)+1)&(~1L))
  25.  
  26. typedef struct {
  27.   long ckID,ckSize;
  28. } Chunk;
  29.  
  30. typedef struct {
  31.   short w,h,x,y;
  32.   char  nPlanes,masking,compression,pad1;
  33.   short transparentColor;
  34.   char  xAspect, yAspect;
  35.   short pageWidth,pageHeight;
  36. } BitMapHeader;
  37.  
  38. short Mode;
  39. unsigned char *pdiskptr;
  40.  
  41. #define SafeRead(a,b,c) if (ReadNEW(a,b,c)==-1L) \
  42.   { CloseNEW(a); return(DISK_ERR); }
  43.  
  44. void *AllocMem(),*AllocRaster(); 
  45.  
  46. /************************************************************************
  47. *                                                                       *
  48. *    Routine name(s) : ReadILBM()                                       *
  49. *    Author          : D. John Hodgson                                  *
  50. *    Environment     : Aztec "C", default                               *
  51. *                                                                       *
  52. *    ReadILBM attempts to read an IFF file into an user-supplied        *
  53. *    bitmap. Returns TRUE if successful. Brushes supported.             *
  54. *                                                                       *
  55. *    OPTIONS : Filespec reflects user-supplied pointer to IFF file in   *
  56. *              RAM if mode argument is non-zero. Otherwise, disk.       *
  57. *                                                                       *
  58. *    LIMITATIONS : Bare-bones ILBM; no masking, CATS/LISTS/PROPS.       *
  59. *                  All other graphics (compressed or not) supported.    *
  60. ************************************************************************/
  61.  
  62. void *OpenNEW(name,accessMode)
  63. unsigned char *name;
  64. long accessMode;
  65. {
  66.   struct FileHandle *Open();
  67.  
  68.   if (!Mode) return(Open(name,accessMode));
  69.  
  70.   pdiskptr=name; /* initialize pseudo-disk RAM ptr */ 
  71.   return(pdiskptr);
  72. }
  73.  
  74. long ReadNEW(file,buffer,length)
  75. struct FileHandle *file;
  76. char *buffer;
  77. long length;
  78. {
  79.   long Read();
  80.  
  81.   if (!Mode) return(Read(file,buffer,length));
  82.  
  83.   movmem(pdiskptr,buffer,(unsigned int)length);
  84.   pdiskptr+=length;
  85.  
  86.   return(length);
  87. }
  88.  
  89. long SeekNEW(file,position,tmode)
  90. struct FileHandle *file;
  91. long position,tmode;
  92. {
  93.   long Seek();
  94.  
  95.   if (!Mode) return(Seek(file,position,tmode));
  96.  
  97.   /* Note : RAM seek only supports one mode : OFFSET_CURRENT! */
  98.   if (tmode!=OFFSET_CURRENT) return(BAD_MODE);
  99.     
  100.   pdiskptr+=position;
  101.  
  102.   return((long)pdiskptr-position); /* Seek() returns previous position! */
  103.  
  104. void CloseNEW(file)
  105. struct FileHandle *file;
  106. {
  107.   if (!Mode) Close(file);
  108. }
  109.  
  110. /* tag : core routines live here! */
  111.  
  112. ReadILBM(fspec,mode,picmap)
  113. char *fspec; /* AmigaDOS filename */
  114. short mode;
  115. struct PicMap *picmap;
  116. {
  117.   struct FileHandle *fp;
  118.   Chunk header;
  119.   BitMapHeader bmhd;
  120.   unsigned char colormap[MAXCOLORS][3],*bufstart,*sourcebuf;
  121.   short i;
  122.   long id;
  123.  
  124.   Mode=mode; 
  125.   setmem(picmap,sizeof(*picmap),0L);
  126.  
  127.   if (!(fp=OpenNEW(fspec,MODE_OLDFILE))) return(DISK_ERR);
  128.  
  129.   SafeRead(fp,&header,(long)sizeof(header));
  130.   if (header.ckID!=ID_FORM) { CloseNEW(fp); return(IFF_ERR); }
  131.  
  132.   SafeRead(fp,&id,(long)sizeof(id));
  133.   if (id!=ID_ILBM) { CloseNEW(fp); return(IFF_ERR); }
  134.  
  135.   for (;;) {
  136.     SafeRead(fp,&header,(long)sizeof(header));
  137.  
  138.     if (header.ckID==ID_BODY) break;
  139.  
  140.     switch(header.ckID) {
  141.       case ID_BMHD: SafeRead(fp,&bmhd,(long)sizeof(bmhd));
  142.  
  143.                     /* force WORD boundary for all pics */
  144.                     bmhd.w=(bmhd.w + 0xf) & 0xfff0;
  145.  
  146.                     break;
  147.  
  148.       case ID_CMAP: SafeRead(fp,&colormap[0][0],(long)header.ckSize);
  149.  
  150.                     for (i=0;i<header.ckSize/3;i++) 
  151.                       picmap->colormap[i]=colormap[i][2]>>4 |
  152.                                           colormap[i][1] & 0xf0 |
  153.                                           (colormap[i][0] & 0xf0)<<4;
  154.                     break;    
  155.  
  156.       case ID_CAMG: SafeRead(fp,&picmap->ViewModes,(long)header.ckSize);
  157.                     break;
  158.  
  159.       default:      SeekNEW(fp,ROUNDODDUP(header.ckSize),OFFSET_CURRENT);
  160.     }
  161.   }
  162.  
  163.   /* make some forced assumptions if CAMG chunk unavailable */
  164.  
  165.   if (!picmap->ViewModes) {
  166.     if (bmhd.w>LOWIDTH) picmap->ViewModes=HIRES;
  167.     if (bmhd.h>LOHEIGHT) picmap->ViewModes|=LACE;
  168.   }
  169.  
  170.   /* Read planes into RAM for ease if decompression */
  171.  
  172.   if (Mode) sourcebuf=bufstart=pdiskptr;  /* memory-resident IFF? */
  173.   else { /* disk-resident IFF? */
  174.     if (!(sourcebuf=bufstart=AllocMem((long)header.ckSize,MEMF_PUBLIC)))
  175.        return(OUT_OF_MEM);
  176.     SafeRead(fp,sourcebuf,(long)header.ckSize); CloseNEW(fp);  
  177.   }
  178.  
  179.   InitBitMap(&picmap->BitMap,(long)bmhd.nPlanes,(long)bmhd.w,(long)bmhd.h);
  180.  
  181.   /* if we -REALLY- need a blank page, zero after allocating! */
  182.  
  183.   for (i=0;i<bmhd.nPlanes;i++)
  184.     if (!(picmap->BitMap.Planes[i]=AllocRaster((long)bmhd.w,(long)bmhd.h))) {
  185.       FreeBitMap(&picmap->BitMap);
  186.       return(OUT_OF_MEM);
  187.     }
  188.  
  189.   i=Expand(&bmhd,bufstart,&picmap->BitMap);
  190.  
  191.   if (!Mode) FreeMem(bufstart,(long)header.ckSize);
  192.  
  193.   return(i); /* error if unpacking prob */
  194. }      
  195.  
  196. FreeBitMap(bitmap)
  197. struct BitMap *bitmap;
  198. {
  199.   short i;
  200.  
  201.   /* take into acct partially allocated maps (due to error) */
  202.  
  203.   for (i=0;i<bitmap->Depth;i++) {
  204.     if (bitmap->Planes[i]) FreeRaster(
  205.        bitmap->Planes[i],(long)bitmap->BytesPerRow*8,(long)bitmap->Rows);
  206.   }
  207.  
  208.   setmem(bitmap,sizeof(bitmap),0L); /* prevent dbl-dealloc errs */
  209. }
  210.  
  211. Expand(bmhd,sourcebuf,bitmap) /* Fast line decompress/deinterleave */
  212. BitMapHeader *bmhd;
  213. register char *sourcebuf;
  214. struct BitMap *bitmap;
  215. {
  216.   register char n,*destbuf; /* in order of preferred allocation */
  217.   register short plane,rowlen,rowbytes,i;
  218.  
  219.   rowlen=(bmhd->w)>>3;
  220.  
  221.   for (i=0;i<bmhd->h;i++) /* process n lines/screen */
  222.     for (plane=0;plane<bmhd->nPlanes;plane++) { /* process n planes/line */
  223.       destbuf=(char *)(bitmap->Planes[plane])+rowlen*i;
  224.  
  225.       if (bmhd->compression==cmpByteRun1) { /* compressed screen? */
  226.         rowbytes=rowlen;
  227.  
  228.         while (rowbytes>0) { /* unpack until 1 scan-line complete */
  229.           n=*sourcebuf++; /* fetch block run marker */
  230.  
  231.           /* uncompressed block? copy n bytes verbatim */
  232.           if (n>=0) {
  233.             ++n;
  234.             movmem(sourcebuf,destbuf,(unsigned int)n);
  235.             rowbytes-=n; destbuf+=n; sourcebuf+=n;
  236.           }
  237.           else { /* compressed block? expand n duplicate bytes */
  238.             n=-n+1;
  239.             setmem(destbuf,(unsigned int)n,(unsigned int)*sourcebuf);
  240.             rowbytes -=n; sourcebuf++; destbuf+=n;
  241.           }
  242.  
  243.         } /* finish unpacking line */
  244.         if (rowbytes) return(EXPAND_ERR); /* shouldn't be any left over! */
  245.       }
  246.       else { /* uncompressed? just copy */
  247.         movmem(sourcebuf,destbuf,(unsigned int)rowlen);
  248.         sourcebuf+=rowlen; destbuf+=rowlen;
  249.       }
  250.     } /* finish interleaved planes, lines */
  251.  
  252.   return(0); /* good result! */
  253. }
  254.